using System;
using System.Collections.Generic;

namespace Pixeldyne.Core.Collections
{
	public interface IPagedList<T>
	{
		int PageItems { get; set; }
		int Pages { get; }
		IList<T> GetPage(int pageNo);
	}

	/// <summary>
	/// Paged generic list.
	/// </summary>
	/// <typeparam name="T"></typeparam>
	[Serializable]
	public class PagedList<T> : List<T>, IPagedList<T>
	{
		private int pageItems = 10;

		/// <summary>
		/// Get/set the number of items per page
		/// </summary>
		public int PageItems
		{
			get { return pageItems; }
			set { pageItems = value; }
		}

		/// <summary>
		/// Returns the total number of pages
		/// </summary>
		public int Pages
		{
			get
			{
				if (Count == 0)
					return 0;

				var pages = (int)Math.Floor(Count / (double)pageItems);

				if (Count % pageItems != 0)
					pages++;

				return pages;
			}
		}

		/// <summary>
		/// Retrieve the specified page of this array
		/// </summary>
		/// <param name="pageNo"></param>
		/// <returns></returns>
		public IList<T> GetPage(int pageNo)
		{
			if (pageNo < 1 || pageNo > Pages)
				throw new IndexOutOfRangeException();

			// make the index 0-based like an array
			pageNo--;

			int startIndex = pageNo * pageItems;
			int endIndex = startIndex + pageItems;

			if (startIndex >= Count)
			{
				return null;
			}

			if (endIndex >= Count)
			{
				endIndex = Count -1;
			}

			IList<T> page = new List<T>();

			for (int i = startIndex; i <= endIndex; i++)
			{
				page.Add(this[i]);
			}

			return page;
		}
	}
}
